package org.myframework;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.myframework.codeutil.CodeGenerator;
import org.myframework.codeutil.Column;
import org.myframework.util.ExceptionUtil;
import org.myframework.util.StringUtil;

public class JDBCCodeGenerator {
	//配置信息目录
	static String configDirectory;

	//数据库配置信息
	private static Properties properties;

	private static Log logger  ;//= LogFactory.getLog(JDBCCodeGenerator.class);

	/**
	 * 获取数据库连接
	 * @return
	 * @throws Exception
	 */
	private static Connection getConnection() throws Exception {
//		Properties properties = loadFromTemplatePath(findJdbcFile());
		Properties localProperties = new Properties();
		localProperties.put("remarksReporting", "true");// 注意这里
		localProperties.put("user", properties.getProperty("jdbc.username"));
		localProperties
				.put("password", properties.getProperty("jdbc.password"));

		// orcl为数据库的SID
		Class.forName(properties.getProperty("jdbc.driver")).newInstance();
		Connection conn = DriverManager.getConnection(
				properties.getProperty("jdbc.url"), localProperties);
		logger.info("读取数据库配置信息：" + properties);
		return conn;
	}

	/**
	 * 判断是否日期
	 * @param dataType
	 * @return
	 */
	private static boolean isDateType(String dataType) {
		String[] dateTypeList = { "TIMESTAMP", "TIME", "DATE" };
		for (String dateType : dateTypeList)
			return StringUtil.contains(dataType.toUpperCase(), dateType);
		return false;
	}

	/**
	 * 根据表名获取字段信息
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	public static List<Column> getLsColumns(String tableName) throws Exception {
		Connection conn = getConnection();
		List<Column> lsColumns = new ArrayList<Column>(10);
		PreparedStatement stmt = conn.prepareStatement("select *  from "
				+ tableName + " where 1=0 ");
		ResultSet resultSet = stmt.executeQuery();
		ResultSetMetaData rsmd = resultSet.getMetaData();
		int n = rsmd.getColumnCount();
		logger.debug("============读取表相关的字段信息 START ================");
		for (int i = 1; i <= n; i++) {
			String colName = rsmd.getColumnName(i);
			String fieldName = StringUtil.toBeanPatternStr(colName);
			String dataType = rsmd.getColumnClassName(i);
			if ("java.math.BigDecimal".equals(dataType)
					&& rsmd.getScale(i) == 0)
				dataType = "Long";
			if ("oracle.sql.CLOB".equals(dataType))
				dataType = "String";
			Column column = new Column();
			column.setName(colName);
			column.setJavaName(fieldName);
			column.setDataType(isDateType(dataType) ? "java.util.Date"
					: dataType);
			column.setPrecision(String.valueOf(rsmd.getPrecision(i)));
			column.setScale(String.valueOf(rsmd.getScale(i)));
			column.setLength(String.valueOf(rsmd.getColumnDisplaySize(i)));
			column.setNullable(String.valueOf(1 == rsmd.isNullable(i)));

			// 获取列注释
			DatabaseMetaData dbmd = conn.getMetaData();
			ResultSet rs = dbmd.getColumns(null, null, tableName, null);
			while (rs.next()) {
				if (colName.equals(rs.getString("COLUMN_NAME"))) {
					String comments = rs.getString("REMARKS");
					column.setComments(StringUtil.asString(comments));
				}
			}
			/*
			 * rs = dbmd.getColumns(null, null, tableName, "%");
			 * while(rs.next()){
			 * System.out.println(rs.getString("COLUMN_NAME")); }
			 */
			// 获取主键列
			ResultSet rs2 = dbmd.getPrimaryKeys(null, null, tableName);
			while (rs2.next()) {
				if (colName.equals(rs2.getString("COLUMN_NAME")))
					column.setColumnKey("TRUE");
			}
			logger.debug("TABLE COLUMN INFO>>>>>" + column
					+ "---------------------");
			lsColumns.add(column);
		}
		logger.debug("============读取表相关的字段信息 END ================");
		return lsColumns;
	}

	public static String findJdbcFile() {
		return configDirectory + "/dropins/codegen/jdbc.properties";
	}

	public static String findTemplatePath() {
		return configDirectory + "/dropins/codegen/templates";
	}

	public static String findTemplateCfgFile() {
		return configDirectory + "/dropins/codegen/templates.cfg";
	}

	public static String findLogs() {
		return configDirectory + "/dropins/codegen/logs";
	}

	protected static Properties loadFromTemplatePath(String propertiesFile)
			throws Exception {
		Properties properties = new Properties();
		InputStream stream = null;
		try {
			String fullPath = propertiesFile;
			stream = new FileInputStream(fullPath);
			properties.load(stream);
		} finally {
			if (stream != null) {
				stream.close();
			}
		}
		return properties;
	}

	/**
	 * 带生成文件配置
	 *
	 * @return
	 * @throws Exception
	 */
	public static List<String> getGenFileList() throws Exception {
		List<String> genFiles = new ArrayList<String>();
		String cfgFile = findTemplateCfgFile();
		FileReader fr = new FileReader(cfgFile);
		BufferedReader br = new BufferedReader(fr);
		while (br.ready()) {
			String line = br.readLine();
			if (!line.startsWith("#") && !"".equals(line.trim()))
				genFiles.add(line);
		}
		br.close();
		fr.close();
		return genFiles;
	}



	/**
	 * 代码生成工具调用
	 *
	 * @param args
	 * @throws Exception
	 */
	public static void exec() {
		CodeGenerator code = new CodeGenerator();
		try {
			properties = loadFromTemplatePath(findJdbcFile());
			code.setTmplDir(findTemplatePath());
			code.putProperties(properties);
			code.setGenFileList(getGenFileList());
			// 代码内容--
			String tableName = properties.getProperty("tableName");
			code.setTablePrefix(properties.getProperty("tablePrefix"));
			code.setPkgPrefix(properties.getProperty("pkgPrefix"));
			code.setModule(properties.getProperty("module"));
			code.setSubModule(properties.getProperty("subModule"));
			code.setTableName(tableName.toUpperCase());
			// 代码存放目录
			code.setJavaSource(properties.getProperty("javaSource"));
			code.setResources(properties.getProperty("resources"));
			code.setWebapp(properties.getProperty("webapp"));

			// 数据库读取配置信息
			code.initCodeTool(getLsColumns(tableName.toUpperCase()));
			code.createCodeByConf();
		} catch (Exception e) {
			logger.error(ExceptionUtil.getStackTrace(e));
			throw new RuntimeException("插件运行失败！检查日志信息！");
		}

	}

	public static void setConfigDirectory(String eclipsePath) {
		JDBCCodeGenerator.configDirectory = eclipsePath;
	}

	public static void setLogger(Log logger) {
		JDBCCodeGenerator.logger = logger;
	}

	public static void main(String[] args) {
		System.setProperty("codegen.root","E:\\");
		JDBCCodeGenerator.setLogger(LogFactory.getLog(JDBCCodeGenerator.class));
		JDBCCodeGenerator.setConfigDirectory("E:\\eclipse-jee-luna-SR1-win32-x86_64\\eclipse\\");
		JDBCCodeGenerator.exec();
	}

}
